package com.tarena.lbs.article.web.service;

import com.alibaba.nacos.common.utils.CollectionUtils;
import com.tarena.lbs.article.web.dao.repository.ArticleRepository;
import com.tarena.lbs.article.web.thread.AuthenticationUtil;
import com.tarena.lbs.attach.api.AttachApi;
import com.tarena.lbs.base.common.utils.Asserts;
import com.tarena.lbs.base.protocol.exception.BusinessException;
import com.tarena.lbs.base.protocol.pager.PageResult;
import com.tarena.lbs.common.content.utils.SequenceGenerator;
import com.tarena.lbs.common.passport.principle.UserPrinciple;
import com.tarena.lbs.pojo.attach.param.PicUpdateParam;
import com.tarena.lbs.pojo.content.entity.ArticleSearchEntity;
import com.tarena.lbs.pojo.content.param.ArticleCategoryParam;
import com.tarena.lbs.pojo.content.param.ArticleContentParam;
import com.tarena.lbs.pojo.content.query.ArticleQuery;
import com.tarena.lbs.pojo.content.vo.ArticleVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class ArticleService {

    @Autowired
    private ArticleRepository articleRepository;

    /**
     * 将条件 组织封装 判断放到业务层 形成一个 query对象
     * 储层根据query非空拼接bool查询es的文章数据
     * @param articleQuery
     * @return
     */
    public PageResult<ArticleVO> articlePage(ArticleQuery articleQuery) throws BusinessException {
        //1.准备一个返回的分页数据
        PageResult<ArticleVO> voPage = assemblePageResult(articleQuery);
        //2.source来源的值 判断 必须不能为空 应该可以使用validation校验@Validate
        Integer source = articleQuery.getSource();
        //3.根据不同分支 组织一个新的查询条件query
        ArticleQuery repositoryQuery = new ArticleQuery();
        if (source == 1){
            //查询来源 手机小程序 TODO
        }else {
            //查询来源是后台 articleTitle articleCategory status 0|草稿 1|发布的文章
            //activityId绑定的活动 startTime endTime userId(文章作者)
            BeanUtils.copyProperties(articleQuery, repositoryQuery);
            repositoryQuery.setUserId(getUserId());
        }
        //4.调用仓储层 获取所有满足repositoryQuery条件的文章列表
        List<ArticleSearchEntity> entities = articleRepository.search(repositoryQuery);
        //5.给分页对象 装配一下vos
        List<ArticleVO> vos = null;
        if(CollectionUtils.isNotEmpty(entities)){
            vos = entities.stream().map(entity->{
                ArticleVO vo = new ArticleVO();
                BeanUtils.copyProperties(entity,vo);
                return vo;
            }).collect(Collectors.toList());
        }
        voPage.setObjects(vos);
        return voPage;
    }

    private PageResult<ArticleVO> assemblePageResult(ArticleQuery articleQuery) {
        PageResult<ArticleVO> voPage = new PageResult<>();
        voPage.setPageNo(1);
        voPage.setPageSize(10);
        voPage.setTotal(100L);
        return voPage;
    }

    private Integer getUserId() throws BusinessException {
        UserPrinciple userPrinciple = AuthenticationUtil.get();
        Asserts.isTrue(userPrinciple==null,new BusinessException("-2","认证解析失败"));
        return userPrinciple.getId();
    }

    public void addArticle(ArticleContentParam articleContentParam) throws BusinessException {
        //1.param转成 entity 写入到es中
        ArticleSearchEntity entity = param2entity(articleContentParam);
        articleRepository.save(entity);
        //2.绑定图片 如果不绑定 XXL-JOB定时任务会定时删除,文章过一段时间就没图片了
        bindPictures(articleContentParam,entity.getId());//封面500 内容 600
    }

    @DubboReference
    private AttachApi attachApi;
    private void bindPictures(ArticleContentParam param, Integer businessId) {
        //每次绑定 都可能是多个图片
        List<PicUpdateParam> pics = new ArrayList<>();
        //1.文章封面 bizType=500 bizId=businessId
        String coverUrl = param.getArticleCover();
        String coverfileUuid = parseUrlFileUuid(coverUrl);
        PicUpdateParam coverParam = new PicUpdateParam();
        coverParam.setBusinessType(500);
        coverParam.setBusinessId(businessId);
        coverParam.setFileUuid(coverfileUuid);
        pics.add(coverParam);
        //2.文章内容的图片绑定 url1,url2,url3,... bizType=600
        String articleMain = param.getArticleMainPic();
        String[] mainUrls = articleMain.split(",");
        List<PicUpdateParam> mainPics = Arrays.stream(mainUrls).map(url->{
            PicUpdateParam picParam = new PicUpdateParam();
            picParam.setBusinessType(500);
            picParam.setBusinessId(businessId);
            picParam.setFileUuid(parseUrlFileUuid(url));
            return picParam;
        }).collect(Collectors.toList());
        pics.addAll(mainPics);
        attachApi.batchUpdateBusiness(pics);
    }

    private String parseUrlFileUuid(String coverUrl) {
        //http://localhost:9081/static/aofeo.png
        return coverUrl.split("/")[4];
    }

    private ArticleSearchEntity param2entity(ArticleContentParam param) throws BusinessException {
        ArticleSearchEntity entity = new ArticleSearchEntity();
        //1.能拷贝的 都拷贝
        BeanUtils.copyProperties(param,entity);
        //2.文章的作者 userId
        UserPrinciple userPrinciple = AuthenticationUtil.get();
        Asserts.isTrue(userPrinciple == null,new BusinessException("-2","认证解析失败"));
        entity.setUserId(userPrinciple.getId());
        //3. 缺少 id 模拟了一个序列化器 生成的Integer数值
        Integer sequence = SequenceGenerator.sequence();
        entity.setId(sequence);
        //4. 时间数据 createTime updateTime
        Date now = new Date();
        entity.setCreateTime(now);
        entity.setUpdateTime(now);
        //5. 地理位置调整格式 location = latitude+","+longitude
        entity.setLocation(param.getLatitude()+","+param.getLongitude());
        //6. 状态判断如果空 自动填充一个0 草稿状态
        if(param.getArticleStatus()==null){
            entity.setArticleStatus(0);
        }
        //7. accessAccount likeAccount favoriteAccount 三个值初始化 后续使用redis的hash 保存数据
        entity.setAccessCount(0);//点击次数
        entity.setLikeCount(0);//点赞次数
        entity.setFavoriteCount(0);//收藏次数
        return entity;
    }
}
